<template>
  <div>
    <img id="dialPanelImg" style="display: none" :src="dial.panel.DIAL_IMG">
    <canvas id="dialCanvas" class="dial-canvas"
            width="20rem" height="20rem"></canvas>
  </div>
</template>

<script>
  export default {
    name: "dial",
    props: {
      //数值
      val: {
        default: 0
      },
      titleName: {
        default: ''
      },
      //图表描述
      dialDetail: {
        default: ''
      },
      //设备是否在线
      onLine: {
        default: '0'
      },
      dialStar: {
        default: 0
      }
    },
    data() {
      return {
        //仪表片宽度
        dialWidth: 0,
        //仪表盘高度
        dialHeight: 0,
        dial: {
          ctx: {},
          panel: {
            width: 0, //宽
            height: 0,//高
            textR: 100 + 10,  //文字半径
            inArcRadius: 80, //内部进度圆半径
            inArcLineWidth: 1, //内部进度圆半径
            outArcRadius: 100, //外部进度圆半径
            outArcLineWidth: 10, //外部进度宽度
            DIAL_IMG: require("@/images/dial_img.png")
          },
          //指针OBJ
          point: {
            //旋转角度
            index: 150,
            offsetR: 83,//指针半径,
            width: 10,
            height: 10,
            startDegree: 135,
            endDegree: 405,
            animationFrameId: 0
          },
          val: 0,
          valMax: 500 // 默认500
        }
      }
    },
    mounted() {
      let that = this;
      let panel = document.getElementById('dialCanvas');


      that.dial.panel.width = panel.width = panel.width * that.getFontSize();
      that.dial.panel.height = panel.height = panel.height * that.getFontSize();
      // that.dial.point.endDegree = that.convertDegrees(that.val) + that.dial.point.startDegree; //设置结束度数
      that.draw();
    },
    watch: {
      val(val, oldVal) {
        console.log(val);
        console.log(oldVal);
      }
    },
    methods: {
      getFontSize() {
        return Number(String(document.documentElement.style.fontSize).replace('px', ''));
      },
      startPath(cxt) {
        cxt.beginPath();
        for (let i = 0; i < 5; i++) {
          let x1 = Math.cos((54 + i * 72) / 180 * Math.PI);
          let y1 = Math.sin((54 + i * 72) / 180 * Math.PI);
          let x2 = Math.cos((18 + i * 72) / 180 * Math.PI) * 0.5;
          let y2 = Math.sin((18 + i * 72) / 180 * Math.PI) * 0.5;
          cxt.lineTo(x2, y2);
          cxt.lineTo(x1, y1);
        }
        cxt.closePath();
      },
      drawStart(cxt, r, x, y, rot) {
        let that = this;
        cxt.save();
        cxt.fillStyle = that.color(that.dialStar);
        cxt.strokeStyle = that.color(that.dialStar);
        cxt.translate(x, y);
        cxt.rotate(rot / 180 * Math.PI);
        cxt.scale(r, r);
        that.startPath(cxt);
        cxt.stroke();
        cxt.restore();
      },
      roundRectColor(ctx, x, y, w, h, r) {
        let that = this;
        ctx.beginPath();
        ctx.save();
        ctx.fillStyle = that.color(that.dialStar);
        ctx.strokeStyle = that.color(that.dialStar);
        ctx.lineJoin = 'round';  //交点设置成圆角
        ctx.lineWidth = r;
        ctx.strokeRect(x + r / 2, y + r / 2, w - r, h - r);
        ctx.fillRect(x + r, y + r, w - r * 2, h - r * 2);
        ctx.stroke();
        ctx.closePath();
        ctx.restore();
      },
      triangle(ctx, x, y, w, h) {
        ctx.beginPath();
        ctx.moveTo(x, y);
        ctx.lineTo(x - w, y - (h / 2));
        ctx.lineTo(x - w, y + (h / 2));
        ctx.fill();
      },
      //指针度数转换（返回指针度数）**【返回从 0 刻度开始的度数：0 之前的部分不需要计算】**
      convertDegrees(val) {
        let degree;
        //首先计算出每个刻度对应的度数
        let de0 = 0.0, de50 = 45.0, de100 = 90.0, de150 = 135.0, de200 = 180.0, de300 = 225.0;
        if (0 <= val && val <= 50) {
          degree = de0 + (((val - 0) / (50 - 0)) * 45);
        } else if (50 < val && val <= 100) {
          degree = de50 + (((val - 50) / (100 - 50)) * 45);
        } else if (100 < val && val <= 150) {
          degree = de100 + (((val - 100) / (150 - 100)) * 45);
        } else if (150 < val && val <= 200) {
          degree = de150 + (((val - 150) / (200 - 150)) * 45);
        } else if (200 < val && val <= 300) {
          degree = de200 + (((val - 200) / (300 - 200)) * 45);
        } else if (300 < val && val <= 500) {
          degree = de300 + (((val - 300) / (500 - 300)) * 45);
        } else {
          alert('表盘参数错误');
        }
        return degree;
      },
      color(dialStar) {
        if (dialStar === 1) {
          return '#ef0806';
        } else if (dialStar === 2) {
          return '#fa7778';
        } else if (dialStar === 3) {
          return '#ffa75a';
        } else if (dialStar === 4) {
          return '#ffcd4e';
        } else if (dialStar === 5) {
          return '#ffef4e';
        } else if (dialStar === 6) {
          return '#d1ff51';
        } else {
          return '#51FF97';
        }
      },
      draw() {
        let that = this;
        let panel = document.getElementById('dialCanvas');
        that.dial.ctx = panel.getContext('2d');
        // // 获取像素比
        let getPixelRatio = function (context) {
          let backingStore = context.backingStorePixelRatio ||
                  context.webkitBackingStorePixelRatio ||
                  context.mozBackingStorePixelRatio ||
                  context.msBackingStorePixelRatio ||
                  context.oBackingStorePixelRatio ||
                  context.backingStorePixelRatio || 1;
          return (window.devicePixelRatio || 1) / backingStore;
        };

        let ratio = getPixelRatio(that.dial.ctx);

        panel.style.width = panel.width + 'px';
        panel.style.height = panel.height + 'px';

        panel.width = panel.width * ratio;
        panel.height = panel.height * ratio;

        // 放大倍数
        that.dial.ctx.scale(ratio, ratio);


        //正式绘制
        that.dial.ctx.clearRect(0, 0, that.dial.panel.width, that.dial.panel.height)

        //内部圆
        that.dial.ctx.save();
        that.dial.ctx.beginPath();
        that.dial.ctx.strokeStyle = 'white';
        that.dial.ctx.lineWidth = that.dial.panel.inArcLineWidth;
        that.dial.ctx.arc(that.dial.panel.width / 2, that.dial.panel.height / 2, that.dial.panel.inArcRadius, 0, 2 * Math.PI, false)
        that.dial.ctx.fillStyle = 'rgba(255,255,255,0.8)'
        that.dial.ctx.drawImage(document.getElementById('dialPanelImg'), (that.dial.panel.width / 2) - that.dial.panel.inArcRadius, (that.dial.panel.height / 2) - that.dial.panel.inArcRadius, that.dial.panel.inArcRadius * 2, that.dial.panel.inArcRadius * 2);
        that.dial.ctx.stroke();
        that.dial.ctx.restore();

        //外部-部分圆
        that.dial.ctx.save();
        that.dial.ctx.beginPath();
        let outArcGradient = that.dial.ctx.createLinearGradient(0, 0, that.dial.panel.width, 0);
        outArcGradient.addColorStop(0.1, "rgba(124,236,92,0.3)");
        outArcGradient.addColorStop(0.2, "rgba(191,246,128,0.3)");
        outArcGradient.addColorStop(0.3, "rgba(242,227,128,0.3)");
        outArcGradient.addColorStop(0.4, "rgba(232,243,128,0.3)");
        outArcGradient.addColorStop(0.5, "rgba(231,226,128,0.3)");
        outArcGradient.addColorStop(0.7, "rgba(226,183,109,0.3)");
        outArcGradient.addColorStop(1.0, "rgba(236,73,59,0.3)");
        that.dial.ctx.strokeStyle = outArcGradient;
        that.dial.ctx.lineWidth = that.dial.panel.outArcLineWidth;
        that.dial.ctx.lineCap = 'round';
        that.dial.ctx.arc(that.dial.panel.width / 2, that.dial.panel.height / 2, that.dial.panel.outArcRadius, Math.PI * 3 / 4, Math.PI / 4, false)
        that.dial.ctx.stroke();
        that.dial.ctx.restore();

        //文字半径
        //参考数【0】计算x，y
        that.dial.ctx.save();
        that.dial.ctx.fillStyle = 'white';
        let y0 = (Math.sin(Math.PI / 4) * that.dial.panel.textR) +  that.dial.panel.height  / 2;
        let x0 = that.dial.panel.width / 2 - (Math.cos(Math.PI / 4) * that.dial.panel.textR);
        that.dial.ctx.font = "15px serif";
        // that.dial.ctx.strokeStyle="#0000ff"
        // that.dial.ctx.fillRect(x0, y0,20,20)
        that.dial.ctx.fillText("0", x0 + 5, y0 + 16);

        //参考数【500】计算x，y
        let y500 = (Math.sin(Math.PI / 4) * that.dial.panel.textR) + that.dial.panel.height / 2;
        let x500 = that.dial.panel.width / 2 + (Math.cos(Math.PI / 4) * that.dial.panel.textR);
        that.dial.ctx.font = "15px serif";
        that.dial.ctx.fillText("500", x500 - 18, y500 + 16);

        //参考数【50】计算x，y
        let y50 = that.dial.panel.height / 2;
        let x50 = that.dial.panel.width / 2 - that.dial.panel.textR;
        that.dial.ctx.font = "15px serif";
        that.dial.ctx.fillText("50", x50 - 15, y50);

        //参考数【300】计算x，y
        let y300 = that.dial.panel.height / 2;
        let x300 = that.dial.panel.width / 2 + that.dial.panel.textR;
        that.dial.ctx.font = "15px serif";
        that.dial.ctx.fillText("300", x300 + 2, y300 + 4);

        //参考数【100】计算x，y
        let y100 = (that.dial.panel.height / 2) - (Math.sin(Math.PI / 4) * that.dial.panel.textR);
        let x100 = (that.dial.panel.width / 2) - (Math.cos(Math.PI / 4) * that.dial.panel.textR);
        that.dial.ctx.font = "15px serif";
        that.dial.ctx.fillText("100", x100 - 20, y100);

        //参考数【200】计算x，y
        let y200 = (that.dial.panel.height / 2) - (Math.sin(Math.PI / 4) * that.dial.panel.textR);
        let x200 = (that.dial.panel.width / 2) + (Math.cos(Math.PI / 4) * that.dial.panel.textR);
        that.dial.ctx.font = "15px serif";
        that.dial.ctx.fillText("200", x200, y200);

        //参考数【150】计算x，y
        let y150 = (that.dial.panel.height / 2) - that.dial.panel.textR;
        let x150 = that.dial.panel.width / 2;
        that.dial.ctx.font = "15px serif";
        that.dial.ctx.fillText("150", x150 - 10, y150);
        that.dial.ctx.restore();

        //绘制指针
        that.dial.ctx.beginPath();
        that.dial.ctx.save();
        that.dial.ctx.translate(that.dial.panel.width / 2, that.dial.panel.height / 2);
        that.dial.ctx.rotate(Math.PI / 180 * (that.convertDegrees(that.val) + that.dial.point.startDegree));
        // that.dial.point.startDegree++;
        that.dial.ctx.translate(-that.dial.panel.width / 2, -that.dial.panel.height / 2);
        that.dial.ctx.fillStyle = 'green';
        that.triangle(that.dial.ctx, that.dial.panel.width / 2 + that.dial.point.offsetR + that.dial.point.width, that.dial.panel.height / 2, that.dial.point.width, that.dial.point.height)
        that.dial.ctx.restore();

        //绘制进度条
        that.dial.ctx.beginPath();
        that.dial.ctx.save();
        let processGradient = that.dial.ctx.createLinearGradient(0, 0, that.dial.panel.width, 0);
        processGradient.addColorStop(0.1, "#51FF97");
        processGradient.addColorStop(0.2, "#d1ff51");
        processGradient.addColorStop(0.3, "#ffef4e");
        processGradient.addColorStop(0.4, "#ffa75a");
        processGradient.addColorStop(0.5, "#fa7778");
        processGradient.addColorStop(0.7, "#ef0806");
        processGradient.addColorStop(1.0, "#740300");
        that.dial.ctx.strokeStyle = processGradient;
        that.dial.ctx.lineWidth = that.dial.panel.outArcLineWidth;
        that.dial.ctx.lineCap = 'round';
        // that.dial.ctx.arc(that.dial.panel.width / 2, that.dial.panel.height / 2, that.dial.panel.outArcRadius, Math.PI * 3 / 4, Math.PI / 180 * that.dial.point.startDegree, false);
        that.dial.ctx.arc(that.dial.panel.width / 2, that.dial.panel.height / 2, that.dial.panel.outArcRadius, Math.PI * 3 / 4, Math.PI / 180 * (that.convertDegrees(that.val) + that.dial.point.startDegree), false);
        that.dial.ctx.stroke();
        that.dial.ctx.restore();

        //绘制文字
        that.dial.ctx.beginPath();
        that.dial.ctx.save();
        that.dial.ctx.fillStyle = 'white';
        that.dial.ctx.font = 'bold 15px sans-serif';
        that.dial.ctx.textAlign = 'center';
        that.dial.ctx.fillText(that.titleName, that.dial.panel.width / 2, that.dial.panel.width * 6.7 / 20); //HCHO指数
        that.dial.ctx.font = 'bold 14px sans-serif';
        that.dial.ctx.fillText(that.dialDetail, that.dial.panel.width / 2, that.dial.panel.width * 10.5 / 20); //空气很棒，适宜居住和活动
        that.dial.ctx.restore();

        //绘制中央分数
        that.dial.ctx.beginPath();
        that.dial.ctx.save();
        that.dial.ctx.font = 'bold 16px sans-serif';
        that.dial.ctx.textAlign = 'center';
        //处理分数颜色(根据星数判断)
        that.dial.ctx.fillStyle = that.color(that.dialStar);
        let valBgWidth = that.dial.ctx.measureText(that.val).width + 20; //方块宽度
        that.roundRectColor(that.dial.ctx, that.dial.panel.width / 2 - (valBgWidth / 2), that.dial.panel.width * 7.6 / 20, valBgWidth, 20, 10);
        that.dial.ctx.fillStyle = '#333';
        that.dial.ctx.fillText(that.val, that.dial.panel.width / 2, that.dial.panel.width * 8.7 / 20);
        that.dial.ctx.restore();

        //绘制五角星
        let fiveStarWidth = 4;
        let fiveStartCount = that.dialStar;
        for (let i = -((fiveStartCount - 1) / 2); i <= ((fiveStartCount - 1) / 2); i++) {
          that.drawStart(that.dial.ctx, fiveStarWidth, that.dial.panel.width / 2 + (i * fiveStarWidth * 5), that.dial.panel.width * 12.2 / 20, 0)
        }

        //处理动画
        // that.dial.point.animationFrameId = requestAnimationFrame(that.draw);
        // if (that.dial.point.startDegree >= that.dial.point.endDegree) {
        //   cancelAnimationFrame(that.dial.point.animationFrameId);
        // }
      },
    },
  }
</script>

<style scoped>
</style>
